/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <节点/节点.h>
#include <matXX.h>

#include "节点/编译声明代码.h"



#define DEF_V3_F_参数 const vec3& data1, const float32 data2, uint8 计算方式
API_EXPORT vec3 f_JIT_Fun_vec3_c_f32(DEF_V3_F_参数);

#define DEF_V3_V3_参数 const vec3& data1, const vec3& data2, uint8 计算方式
API_EXPORT vec3 f_JIT_Fun_vec3_c_vec3(DEF_V3_V3_参数);

API_EXPORT S_Vec3Array* f_JIT_Fun_vec3s_c_vec3s(const S_Vec3Array* v1, const S_Vec3Array* v2, S_Vec3Array* r, int32 方式);

API_EXPORT void	f_JIT_Fun_F32s_c_F32s(S_F32Array* r, S_F32Array* a, S_F32Array* b, uint8 方式);
API_EXPORT void	f_JIT_单值数组计算(S_I32Array* r, S_I32Array* a, S_I32Array* b, uint8 方式);
API_EXPORT void	f_JIT_单值累计计算(S_F32Array* r, S_F32Array* a, uint8 方式);
API_EXPORT float32	f_JIT_单值合并计算(S_F32Array* r, uint8 方式);


API_EXPORT void f_JIT_Fn_三角函数s(S_F32Array* inData, S_F32Array* outData, uint8 type);
API_EXPORT float32 f_JIT_Fn_三角函数(float32 inData, uint8 type);

API_EXPORT void f_JIT_Fn_向量归一化s(S_Vec3Array* inData, S_Vec3Array* outData);

API_EXPORT void f_JIT_Fn_逻辑计算m(S_F32Array* inDataA, S_F32Array* inDataB, S_I8Array* outData, uint8 方式);
API_EXPORT void f_JIT_Fn_逻辑计算(float32 inDataA, float32 inDataB, int8& outData, uint8 方式);

API_EXPORT void f_JIT_Fn_单目计算m(S_F32Array* inDataA, S_F32Array* outData, int32 方式);

API_EXPORT void f_JIT_Fn_矢量逻辑计算m(S_Vec3Array* inDataA, S_Vec3Array* inDataB, S_I8Array* outData, uint8 方式);
API_EXPORT void f_JIT_Fn_矢量逻辑计算(float32 inDataA, float32 inDataB, int8& outData, uint8 方式);

//vec3 f_JIT_Fn_向量归一化(const vec3& inData, uint8 type);
API_EXPORT vec3 f_JIT_Fn_设置矢量分量(const vec3& 矢量, float32 分量, int8 分量ID);
API_EXPORT void f_JIT_Fn_设置矢量分量m(const S_Vec3Array* 矢量, const S_F32Array* 分量, int8 分量ID, S_Vec3Array* 返回矢量);

API_EXPORT void f_JIT_Fn_混合m(const S_F32Array* a, const S_F32Array* b, const S_F32Array* c, S_F32Array* 返回矢量);
API_EXPORT void f_JIT_Fn_矢量混合m(const S_Vec3Array* a, const S_Vec3Array* b, const S_F32Array* c, S_Vec3Array* 返回矢量);

API_EXPORT void f_JIT_旋转向量节点(S_Vec3Array* 向量, const S_Vec3Array* 法线, const S_Vec2Array* UV, uint8 方式);

API_EXPORT void f_JIT_曲线采样(S_F32Array* 值, const S_曲线& curve, const S_F32Array* 步进, const vec2& 钳制 = { 1,1 });




Inline float32 f_JIT_步进f(float32& x, float32& edge, uint8 方式) {
	switch (方式) {
		case 0: return step(edge, x);
		case 1: return int32(x / edge);
		case 2: {
			float32 a = x /edge;
			return x - int32(a) * edge;
		}
		case 3: {
			int32 a = (x / edge);
			return (x - a * edge) < 1 ? 1 : 0;
		}
		case 4: {
			return x += edge;
			break;
		}
		case 5: {
			return x -= edge;
			break;
		}
		default:
			break;
	}
	return 0;
}
Inline int32 f_JIT_步进i(int32& x, int32& edge, uint8 方式) {
	switch (方式) {
		case 0: return step(edge, x);
		case 1: return int32(x / edge);
		case 2: {
			float32 a = x / edge;
			return x - int32(a) * edge;
		}
		case 3: {
			int32 a = (x / edge);
			return (x - a * edge) < 1 ? 1 : 0;
		}
		case 4: {
			return x += edge;
			break;
		}
		case 5: {
			return x -= edge;
			break;
		}
		default:
			break;
	}
	return 0;
}
API_EXPORT void f_JIT_步进fm(const S_F32Array* x, const S_F32Array* y, S_F32Array* a, uint8 方式);
API_EXPORT void f_JIT_步进im(const S_I32Array* x, const S_I32Array* y, S_I32Array* a, uint8 方式);


Inline vec3 f_JIT_坐标变换(const vec3& vert, const vec3& loc, const vec3& rot, const vec3& scal) {
	auto mat = f_mat44_构建XYZ变换矩阵({loc, rot, scal});
	return mat * vert;
}
API_EXPORT void f_JIT_坐标变换m(const S_Vec3Array* vert, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal, S_Vec3Array* r);




Inline uint32 f_JIT_位运算U(uint32 a, uint32 b, uint8 方式) {
	//auto c = a << b;
	//std::cout<<c<<std::endl;
	switch (方式) {
		case 0: return a | b;
		case 1: return a & b;
		case 2: return a ^ b;
		case 3: return a << b;
		case 4: return a >> b;
	}
	return 0;
}
Inline void f_JIT_位运算Uxx(uint32& a, const uint32& b, uint8 方式) {
	switch (方式) {
		case 0: a |= b; break;
		case 1: a &= b; break;
		case 2: a ^= b; break;
		case 3: a <<= b; break;
		case 4: a >>= b; break;
	}
}

API_EXPORT void f_JIT_位运算Um(const S_UI32Array* x, const S_UI32Array* y, S_UI32Array* a, uint8 方式);

API_EXPORT void f_JIT_体素统计_轴向个数(const S_I8Array* 体素, const vec3 比对坐标, int32 轴向, S_I32Array* 个数);
API_EXPORT void f_JIT_体素统计_轴向空洞(const S_I8Array* 体素, const int8 值, int32 轴向, S_I32Array* 个数);
API_EXPORT void f_JIT_体素统计_索引坐标(const S_Vec3Array* 体素, S_I32Array* 个数);

//API_EXPORT void f_JIT_空间邻近_距离(const S_Vec3Array* vert, const S_Vec3Array* 比对坐标, S_F32Array* 距离);
//API_EXPORT void f_JIT_空间邻近_合并(const S_Vec3Array* vert, const S_Vec3Array* 比对坐标, S_Vec3Array* 合并);
API_EXPORT void f_JIT_空间邻近_体素遮罩(const S_Vec3Array* 坐标, const S_Vec3Array* 体素, float32 容差, S_I8Array* 遮罩);
API_EXPORT void f_JIT_空间邻近_体素索引(const S_Vec3Array* 主坐标, const S_Vec3Array* 从坐标, int8 轴向, S_UI32Array* 索引);
API_EXPORT void f_JIT_空间邻近_体素(const S_Vec3Array* vert, const S_Vec3Array* 比对坐标, float32 容差, int8 轴向, S_I8Array* 索引);
API_EXPORT void f_JIT_空间邻近_轴向最近距离(const S_Vec3Array* vert, const S_Vec3Array* 比对坐标, int8 轴向, bool 反向, S_F32Array* 最近距离);
API_EXPORT void f_JIT_空间邻近_轴向最近索引(const S_Vec3Array* vert, const S_Vec3Array* 比对坐标, int8 轴向, bool 反向, S_UI32Array* 最近索引);
//API_EXPORT void f_JIT_体素统计();

API_EXPORT void f_node_所有计算类节点JIT初始化();



